package pe.com.cotelasa.scp.dao.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import pe.com.cotelasa.common.dao.DaoImpl;
import pe.com.cotelasa.common.dao.excepcion.DAOException;
import pe.com.cotelasa.scp.dao.IDAOArticuloSede;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.entidad.ArticuloSede;
import pe.com.cotelasa.scp.entidad.ArticuloSedePK;
import pe.com.cotelasa.scp.entidad.Empresa;
import pe.com.cotelasa.scp.entidad.Sede;

@SuppressWarnings("serial")
@Repository("daoArticuloSede")
public class DAOArticuloSedeImp extends DaoImpl<ArticuloSede, Integer> implements IDAOArticuloSede, Serializable {

    @SuppressWarnings("unchecked")
    @Override
    @Transactional
    public Collection<ArticuloSede> listaArticulosPorSedeConStock(ArticuloSede articuloSede)
            throws DAOException {
        try {
            return sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .add(Restrictions.eq("id.idEmpresa", articuloSede.getId().getIdEmpresa()))
                    .add(Restrictions.eq("id.idSede", articuloSede.getId().getIdSede()))
                    .add(Restrictions.gt("caStockDisponible", BigDecimal.ZERO))
                    .add(Restrictions.eq("esRegistro",
                    String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor()))).list();

        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    @Transactional
    public ArticuloSede buscarArticuloSede(ArticuloSede articuloSede) throws DAOException {
        sessionFactory.getCurrentSession().flush();
        return (ArticuloSede) sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                .add(Restrictions.eq("id.idEmpresa", articuloSede.getId().getIdEmpresa()))
                .add(Restrictions.eq("id.idArticulo", articuloSede.getId().getIdArticulo()))
                .add(Restrictions.eq("id.idSede", articuloSede.getId().getIdSede()))
                .add(Restrictions.eq("id.partidaLote", articuloSede.getId().getPartidaLote()))
                .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())))
                .uniqueResult();
    }

    @Override
    public Collection<ArticuloSede> listaArticulosUnicosPorSede(ArticuloSede articuloSede) throws DAOException {
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .createAlias("articulo", "ar")
                    .createAlias("articulo.idCategoriaArticulo", "ca")
                    .add(Restrictions.eq("id.idEmpresa", articuloSede.getId().getIdEmpresa()))
                    .add(Restrictions.eq("id.idSede", articuloSede.getId().getIdSede()))
                    .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())));

            System.out.println("id categoria: " + articuloSede.getArticulo().getIdCategoriaArticulo());
            if (articuloSede.getArticulo().getIdCategoriaArticulo() != null) {
                query = query.add(Restrictions.disjunction()
                        .add(Restrictions.eq("ar.idCategoriaArticulo", articuloSede.getArticulo().getIdCategoriaArticulo()))
                        .add(Restrictions.eq("ca.idCategoriaArticulo", articuloSede.getArticulo().getIdCategoriaArticulo())));
            }

            query = query.setProjection(Projections.distinct(Projections.property("id.idArticulo")));

            return query.list();

        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }

    @Override
    public Collection<ArticuloSede> listaArticulosParaAjuste(ArticuloSede articuloSede, Integer[] listaId) throws DAOException {
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())))
                    .add(Restrictions.like("id.partidaLote", "%" + articuloSede.getId().getPartidaLote() + "%"))
                    .add(Restrictions.eq("id.idEmpresa", articuloSede.getId().getIdEmpresa()));

            if (articuloSede.getId().getIdSede() != 0) {
                query = query.add(Restrictions.eq("id.idSede", articuloSede.getId().getIdSede()));
            }
            if (articuloSede.getId().getIdSede() == 0) {
                query = query.add(Restrictions.in("id.idSede", listaId));
            }
            if (articuloSede.getId().getIdArticulo() != 0) {
                System.out.println("entroooo a articulo: " + articuloSede.getId().getIdArticulo());
                query = query.add(Restrictions.eq("id.idArticulo", articuloSede.getId().getIdArticulo()));
            }

            return query.list();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }

    @Override
    public Collection<ArticuloSede> listaStockPorFiltro(ArticuloSede articuloSede) throws DAOException {
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .createAlias("articulo", "ar")
                    .createAlias("articulo.idCategoriaArticulo", "ca")
                    .add(Restrictions.eq("empresa", articuloSede.getEmpresa()))
                    .addOrder(Order.desc("fecCreacion"))
                    .add(Restrictions.ne("caStockDisponible", BigDecimal.ZERO))
                    .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())));
            if (!articuloSede.getArticulo().getModelo().equalsIgnoreCase("")) {
                query = query.add(Restrictions.eq("ar.modelo", articuloSede.getArticulo().getModelo()));
            }
            if (!articuloSede.getCodigoCliente().equalsIgnoreCase("")) {
                query = query.add(Restrictions.eq("codigoCliente", articuloSede.getCodigoCliente()));
            }
            if (articuloSede.getSede() != null) {
                query = query.add(Restrictions.eq("sede", articuloSede.getSede()));
            }
            if (articuloSede.getArticulo().getId() != 0) {
                query = query.add(Restrictions.eq("articulo.id", articuloSede.getArticulo().getId()));
            }
            if (articuloSede.getArticulo().getIdCategoriaArticulo() != null) {
                query = query.add(Restrictions.disjunction()
                        .add(Restrictions.eq("ar.idCategoriaArticulo", articuloSede.getArticulo().getIdCategoriaArticulo()))
                        .add(Restrictions.eq("ca.idCategoriaArticulo", articuloSede.getArticulo().getIdCategoriaArticulo())));
            }

            return query.list();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }

    @Override
    public Collection<ArticuloSede> listaArticulosParaReporte(ArticuloSede articuloSede) throws DAOException {
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .createAlias("articulo", "ar")
                    .createAlias("articulo.idCategoriaArticulo", "ca")
                    .addOrder(Order.desc("ca.nombre"))
                    .addOrder(Order.desc("sede"))
                    .addOrder(Order.desc("articulo"))
                    .add(Restrictions.eq("empresa", articuloSede.getEmpresa()))
                    .add(Restrictions.ne("caStockDisponible", BigDecimal.ZERO))
                    .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())))
                    .add(Restrictions.eq("ca.idCategoriaArticulo", articuloSede.getArticulo().getIdCategoriaArticulo()));

            return query.list();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }

    @Override
    public Collection<ArticuloSede> listaArticulosPorNombre(ArticuloSede articuloSede) throws DAOException {
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(ArticuloSede.class)
                    .createAlias("articulo", "ar")
                    .addOrder(Order.desc("ar.nombreComercial"))
                    .add(Restrictions.like("ar.nombreComercial", "%" + articuloSede.getArticulo().getNombreComercial() + "%"))
                    .add(Restrictions.eq("esRegistro", String.valueOf(ESTADO_REGISTRO.ACTIVO.getValor())))
                    .add(Restrictions.eq("id.idSede", articuloSede.getId().getIdSede()))
                    .add(Restrictions.gt("caStockDisponible", BigDecimal.ZERO))
                    .add(Restrictions.eq("id.idEmpresa", articuloSede.getId().getIdEmpresa()));

            return query.list();
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }
    }
}
